home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / supp.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  13KB  |  419 lines

  1. #include "supp.h"
  2.  
  3. static char FILE_[]=__FILE__;
  4.  
  5. char *typname[]={"strange","char","short","int","long","float","double","void",
  6.                  "pointer","array","struct","union","enum","function"};
  7. char *storage_class_name[]={"strange","auto","register","static","extern","typedef"};
  8.  
  9. char *ename[]={"strange","sequence","move","set+","set-","set*","set/","set%",
  10.                "set&","set^","set|","set<<","set>>","?:","lor","land","or",
  11.                "eor","and","equal","unequal","lt","le","gt","ge","lsl",
  12.                "lsr","add","sub","mul","div","mod","negate",
  13.                "not","preinc","postinc","predec","postdec","neg",
  14.                "dref-pointer","address-of","cast","call","index",
  15.                "dref-struct-pointer","dref-struct","identifier","constant",
  16.                "string","member",
  17.                 "convert-char","convert-short","convert-int","convert-long",
  18.                 "convert-float","convert-double","convert-void","convert-pointer",
  19.                 "convert-uchar","convert-ushort","convert-uint","convert-ulong",
  20.                 "address-of-array","first-element-of-array","pmult",
  21.                 "allocreg","freereg","pconstant","test","label","beq","bne",
  22.                 "blt","bge","ble","bgt","bra","compare","push","pop",
  23.                 "address-of-struct","add-int-to-pointer","sub-int-from-pointer",
  24.                 "sub-pointer-from-pointer","push-reg","pop-reg","pop-args",
  25.                 "save-regs","restore-regs","identifier-label","dc","align",
  26.                 "colon","get-return","set-return","move-from-reg","move-to-reg",
  27.                 "nop"};
  28.  
  29. char *empty="";
  30. zchar vchar; zuchar vuchar;
  31. zshort vshort; zushort vushort;
  32. zint vint; zuint vuint;
  33. zlong vlong; zulong vulong;
  34. zfloat vfloat; zdouble vdouble;
  35. zpointer vpointer;
  36.  
  37. #ifndef DEBUG
  38. int DEBUG;
  39. #endif
  40.  
  41. int label;
  42.  
  43. int regs[MAXR+1],regused[MAXR+1];
  44. struct Var *regsv[MAXR+1];
  45. int goto_used;
  46. int ic_count;
  47. zlong max_offset;
  48. int function_calls;
  49. int multiple_ccs;
  50. int lastlabel,return_label;
  51. int only_inline;
  52. struct IC *err_ic;
  53. long maxoptpasses=10;
  54. long optflags;
  55. long inline_size=100;
  56. long unroll_size=200;
  57. long fp_assoc,noaliasopt;
  58. int fline;
  59. char errfname[FILENAME_MAX+1];
  60. struct IC *first_ic,*last_ic;
  61. int float_used;
  62. /*  Das haette ich gern woanders    */
  63. struct Var *vl1,*vl2,*vl3;
  64.  
  65.  
  66. struct Typ *clone_typ(struct Typ *old)
  67. /*  Erzeugt Kopie eines Typs und liefert Zeiger auf Kopie.  */
  68. {
  69.   struct Typ *new;
  70.   if(!old) return(0);
  71.   new=mymalloc(TYPS);
  72.   *new=*old;
  73.   if(new->next) new->next=clone_typ(new->next);
  74.   return(new);
  75. }
  76. void free_IC(struct IC *p)
  77. /*  Gibt IC-Liste inkl. Typen frei.                 */
  78. {
  79.   struct IC *merk;
  80.   if(DEBUG&1) printf("free_IC()\n");
  81.   while(p){
  82.     if(p->q1.am) free(p->q1.am);
  83.     if(p->q2.am) free(p->q2.am);
  84.     if(p->z.am) free(p->z.am);
  85.     merk=p->next;
  86.     free(p);
  87.     p=merk;
  88.   }
  89. }
  90. void remove_IC(struct IC *p)
  91. /*  Entfernt IC p aus Liste. */
  92. {
  93.   if(p->prev) p->prev->next=p->next; else first_ic=p->next;
  94.   if(p->next) p->next->prev=p->prev; else last_ic=p->prev;
  95.   if(p->q1.am) free(p->q1.am);
  96.   if(p->q2.am) free(p->q2.am);
  97.   if(p->z.am) free(p->z.am);
  98.   free(p);
  99. }
  100. void freetyp(struct Typ *p)
  101. /* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so. */
  102. {
  103.   int f;struct Typ *merk;
  104.   if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
  105.   while(p){
  106.     merk=p->next;
  107.     f=p->flags&NQ;
  108.     if(merk&&f!=ARRAY&&f!=POINTER&&f!=FUNKT){ierror(0);return;}
  109.     free(p);
  110.     p=merk;
  111.   }
  112. }
  113. zlong falign(struct Typ *t)
  114. /*  Liefert Alignment eines Typs. Funktioniert im Gegensatz zum  */
  115. /*  align[]-Array auch mit zusammengesetzten Typen.              */
  116. {
  117.   int i,f; zlong al,alt;
  118.   f=t->flags&NQ;
  119.   al=align[f];
  120.   if(f<=POINTER) return al;
  121.   if(f==ARRAY){
  122.     do{ 
  123.       t=t->next; 
  124.       f=t->flags&NQ;
  125.     }while(f==ARRAY);
  126.     alt=falign(t);
  127.     if(zlleq(al,alt)) return alt; else return al;
  128.   }
  129.   if(f==UNION||f==STRUCT){
  130.     for(i=0;i<t->exact->count;i++){
  131.       alt=falign((*t->exact->sl)[i].styp);
  132.       if(!zlleq(alt,al)) al=alt;
  133.     }
  134.     return al;
  135.   }
  136.   return al;
  137. }
  138. zlong szof(struct Typ *t)
  139. /*  Liefert die benoetigte Groesse eines Typs in Bytes.     */
  140. {
  141.   int i=t->flags&NQ,j;zlong size,m;
  142.   if(i<=POINTER) return sizetab[i];
  143.   if(i==ARRAY){
  144.     size=zlmult((t->size),szof(t->next));
  145.     m=align[ARRAY];
  146.     return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
  147.   }
  148.   if(i==UNION){
  149.     for(j=0,size=l2zl(0L);j<t->exact->count;j++){
  150.       m=szof((*t->exact->sl)[j].styp);
  151.       if(zleqto(m,l2zl(0L))) return(l2zl(0L));
  152.       if(!zlleq(m,size)) size=m;
  153.     }
  154.     m=falign(t);
  155.     return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
  156.   }
  157.   if(i==STRUCT){
  158.     for(j=0,size=0;j<t->exact->count;j++){
  159.       struct Typ *h=(*t->exact->sl)[j].styp;
  160.       m=falign(h);
  161.       size=zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m);
  162.       m=szof(h);
  163.       if(zleqto(m,l2zl(0L))) return(l2zl(0L));
  164.       size=zladd(size,m);
  165.     }
  166.     m=falign(t);
  167.     return zlmult(zldiv(zladd(size,zlsub(m,l2zl(1L))),m),m); /* align */
  168.   }
  169.   return sizetab[i];
  170. }
  171. void printval(FILE *f,union atyps *p,int t,int verbose)
  172. /*  Gibt atyps aus.                                     */
  173. {
  174.   if(t==CHAR){if(verbose)fprintf(f,"C");vlong=zc2zl(p->vchar);printzl(f,vlong);}
  175.   if(t==(UNSIGNED|CHAR)){if(verbose)fprintf(f,"UC");vulong=zuc2zul(p->vuchar);printzul(f,vulong);}
  176.   if(t==SHORT){if(verbose)fprintf(f,"S");vlong=zs2zl(p->vshort);printzl(f,vlong);}
  177.   if(t==(UNSIGNED|SHORT)){if(verbose) fprintf(f,"US");vulong=zus2zul(p->vushort);printzul(f,vulong);}
  178.   if(t==FLOAT){if(verbose)fprintf(f,"F");vdouble=zf2zd(p->vfloat);printzd(f,vdouble);}
  179.   if(t==DOUBLE){if(verbose)fprintf(f,"D");printzd(f,p->vdouble);}
  180.   if(t==INT){if(verbose)fprintf(f,"I");vlong=zi2zl(p->vint);printzl(f,vlong);}
  181.   if(t==LONG){if(verbose)fprintf(f,"L");printzl(f,p->vlong);}
  182.   if(t==(UNSIGNED|INT)){if(verbose)fprintf(f,"UI");vulong=zui2zul(p->vuint);printzul(f,vulong);}
  183.   if(t==(UNSIGNED|LONG)){if(verbose)fprintf(f,"UL");printzul(f,p->vulong);}
  184.   /*  das hier ist nicht wirklich portabel    */
  185.   if(t==POINTER){if(verbose)fprintf(f,"P");vulong=zp2zul(p->vpointer);printzul(f,vulong);}
  186. }
  187. void pric2(FILE *f,struct IC *p)
  188. /*  Gibt ein IC aus.  */
  189. {
  190.   if(p->next&&p->next->prev!=p) ierror(0);
  191.   if(p->code>=LABEL&&p->code<=BRA){
  192.     if(p->code==LABEL)
  193.       fprintf(f,"L%d",p->typf);
  194.     else{
  195.       fprintf(f,"\t%s L%d",ename[p->code],p->typf);
  196.       if(p->q1.flags){ fprintf(f,",");probj(f,&p->q1,0);}
  197.     }
  198.   }else{
  199.     fprintf(f,"\t%s ",ename[p->code]);
  200.     if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
  201.     if(p->typf) fprintf(f,"%s ",typname[p->typf&NQ]);
  202.     probj(f,&p->q1,p->typf);
  203.     if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,p->typf);}
  204.     if(p->z.flags){fprintf(f,"->");probj(f,&p->z,p->typf);}
  205.     if(p->code==ASSIGN||p->code==PUSH||p->code==POP||p->code==CALL)
  206.       fprintf(f," size=%ld",zl2l(p->q2.val.vlong));
  207.     if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg)
  208.       fprintf(f," except %s",regnames[p->q1.reg]);
  209.   }
  210.   fprintf(f,"\n");
  211. }
  212. void pric(FILE *f,struct IC *p)
  213. /*  Gibt IC-Liste auf dem Bildschirm aus.             */
  214. {
  215.   while(p){
  216.     pric2(f,p);
  217. /*        if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/
  218.     p=p->next;
  219.   }
  220. }
  221. void printzl(FILE *f,zlong x)
  222. /*  Konvertiert zlong nach ASCII.                       */
  223. /*  Basiert noch einigermassen auf                      */
  224. /*  Zweierkomplementdarstellung (d.h. -MIN>MAX).        */
  225. /*  Ausserdem muss max(abs(long))<=max(unsigned long).  */
  226. {
  227.   zlong zl;zulong zul;
  228.   zl=l2zl(0L);
  229.   if(zlleq(x,zl)&&!zleqto(x,l2zl(0L))){
  230.     fprintf(f,"-");zl=zul2zl(t_max[LONG]);
  231.     if(zlleq(x,zlsub(l2zl(0L),zl))&&!zleqto(x,zlsub(l2zl(0L),zl))){
  232.       /*  aufpassen, da -x evtl. >LONG_MAX    */
  233.       zul=t_max[LONG];
  234.       x=zladd(x,zl);
  235.     } else zul=ul2zul(0UL);
  236.     x=zlsub(l2zl(0L),x);
  237.     vulong=zl2zul(x);
  238.     zul=zuladd(zul,vulong);
  239.   }else zul=zl2zul(x);
  240.   printzul(f,zul);
  241. }
  242. void printzul(FILE *f,zulong x)
  243. /*  Konvertiert zulong nach ASCII.                      */
  244. {
  245.   zulong zul;unsigned long l;
  246.   zul=ul2zul(10UL);
  247.   if(!zuleqto(zuldiv(x,zul),ul2zul(0UL))) printzul(f,zuldiv(x,zul));
  248.   zul=zulmod(x,zul);l=zul2ul(zul);
  249.   fprintf(f,"%c",(int)(l+'0'));
  250. }
  251. void printzd(FILE *f,zdouble x)
  252. /*  Konvertiert zdouble nach ASCII, noch nicht fertig.  */
  253. {
  254.   fprintf(f,"fp-constant");
  255. }
  256. void *mymalloc(size_t size)
  257. /*  Belegt Speicher mit Abfrage.    */
  258. {
  259.   void *p;static int safe;
  260.   /*  Um ein Fehlschlagen bei size==0 zu vermeiden; nicht sehr schoen,    */
  261.   /*  aber das einfachste...                                              */
  262.   if(size==0) size=1;
  263.   if(!(p=malloc(size))){
  264.     error(12);
  265.     raus();
  266.   }
  267.   return(p);
  268. }
  269. void probj(FILE *f,struct obj *p,int t)
  270. /*  Gibt Objekt auf Bildschirm aus.                    */
  271. {
  272.   if(p->am) ierror(0);
  273.   if(p->flags&DREFOBJ) fprintf(f,"(");
  274.   if(p->flags&VARADR) fprintf(f,"#");
  275.   if(p->flags&VAR) {
  276.     printval(f,&p->val,LONG,1);
  277.     if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){
  278.       if(p->flags®)
  279.     fprintf(f,"+%s",regnames[p->reg]);
  280.       else
  281.     fprintf(f,"+%ld(FP)", zl2l(p->v->offset));
  282.     }else{
  283.       if(p->v->storage_class==STATIC){
  284.     fprintf(f,"+L%ld",zl2l(p->v->offset));
  285.       }else{
  286.     fprintf(f,"+_%s",p->v->identifier);
  287.       }
  288.     }
  289.     fprintf(f,"(%s)",p->v->identifier);
  290.     if(p->v->reg) fprintf(f,":%s",regnames[abs(p->v->reg)]);
  291.   }
  292.   if((p->flags®)&&!(p->flags&VAR)) fprintf(f,"%s",regnames[p->reg]);
  293.   if(p->flags&KONST){
  294.     fprintf(f,"#");printval(f,&p->val,t&NU,1);
  295.   }
  296.   if(p->flags&DREFOBJ) fprintf(f,")");
  297. }
  298. void prl(FILE *o,struct struct_declaration *p)
  299. /* Gibt eine struct_declaration auf dem Bildschirm aus. */
  300. {
  301.   int i;
  302.   for(i=0;i<p->count;i++) {fprintf(o," %d.:",i); prd(o,(*p->sl)[i].styp);}
  303. }
  304. void prd(FILE *o,struct Typ *p)
  305. /* Gibt einen Typ auf dem Bildschirm aus.    */
  306. {
  307.   int f;
  308.   if(!p) {fprintf(o,"empty type ");return;}
  309.   f=p->flags;
  310. /*    fprintf(o,"(Sizeof=%ld,flags=%d)",zl2l(szof(p)),f);*/
  311. /*    if(type_uncomplete(p)) {fprintf(o,"incomplete ");}*/
  312.   if(f&CONST) {fprintf(o,"const ");f&=~CONST;}
  313.   if(f&STRINGCONST) {fprintf(o,"string-const ");f&=~STRINGCONST;}
  314.   if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;}
  315.   if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;}
  316.   if(f==FUNKT){
  317.     fprintf(o,"function with parameters (");
  318.     prl(o,p->exact);
  319.     fprintf(o,") returning ");prd(o,p->next);return;
  320.   }
  321.   if(f==STRUCT){
  322.     fprintf(o,"struct with components {");
  323.     prl(o,p->exact);fprintf(o,"} ");
  324.     return;
  325.   }
  326.   if(f==UNION){
  327.     fprintf(o,"union with components {");
  328.     prl(o,p->exact);fprintf(o,"} ");
  329.     return;
  330.   }
  331.   if(f==POINTER) {fprintf(o,"pointer to ");prd(o,p->next);return;}
  332.   if(f==ARRAY) {fprintf(o,"array [size %ld] of ",zl2l(p->size));prd(o,p->next);return;}
  333.   fprintf(o,"%s",typname[f]);
  334. }
  335.  
  336. void insert_const2(union atyps *p,int t)
  337. /*  Traegt Konstante in entprechendes Feld ein.       */
  338. {
  339.   if(!p) ierror(0);
  340.   t&=NU;
  341.   if(t==CHAR) {p->vchar=vchar;return;}
  342.   if(t==SHORT) {p->vshort=vshort;return;}
  343.   if(t==INT) {p->vint=vint;return;}
  344.   if(t==LONG) {p->vlong=vlong;return;}
  345.   if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;}
  346.   if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;}
  347.   if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;}
  348.   if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;}
  349.   if(t==FLOAT) {p->vfloat=vfloat;return;}
  350.   if(t==DOUBLE) {p->vdouble=vdouble;return;}
  351.   if(t==POINTER) {p->vpointer=vpointer;return;}
  352. }
  353. void eval_const(union atyps *p,int t)
  354. /*  Weist bestimmten globalen Variablen Wert einer CEXPR zu.       */
  355. {
  356.   int f=t&NQ;
  357.   if(!p) ierror(0);
  358.   if(f>=CHAR&&f<=LONG){
  359.     if(!(t&UNSIGNED)){
  360.       if(f==CHAR) vlong=zc2zl(p->vchar);
  361.       if(f==SHORT)vlong=zs2zl(p->vshort);
  362.       if(f==INT)  vlong=zi2zl(p->vint);
  363.       if(f==LONG) vlong=p->vlong;
  364.       vulong=zl2zul(vlong);
  365.       vdouble=zl2zd(vlong);
  366.     }else{
  367.       if(f==CHAR) vulong=zuc2zul(p->vuchar);
  368.       if(f==SHORT)vulong=zus2zul(p->vushort);
  369.       if(f==INT)  vulong=zui2zul(p->vuint);
  370.       if(f==LONG) vulong=p->vulong;
  371.       vlong=zul2zl(vulong);
  372.       vdouble=zul2zd(vulong);
  373.     }
  374.     vpointer=zul2zp(vulong);
  375.   }else{
  376.     if(f==POINTER){
  377.       vulong=zp2zul(p->vpointer);
  378.       vlong=zul2zl(vulong);vdouble=zul2zd(vulong);
  379.     }else{
  380.       if(f==FLOAT) vdouble=zf2zd(p->vfloat); else vdouble=p->vdouble;
  381.       vlong=zd2zl(vdouble);
  382.       vulong=zl2zul(vlong);
  383.     }
  384.   }
  385.   vfloat=zd2zf(vdouble);
  386.   vuchar=zul2zuc(vulong);
  387.   vushort=zul2zus(vulong);
  388.   vuint=zul2zui(vulong);
  389.   vchar=zl2zc(vlong);
  390.   vshort=zl2zs(vlong);
  391.   vint=zl2zi(vlong);
  392. }
  393.  
  394. struct function_info *new_fi(void)
  395. /*  Belegt neue function_info-Struktur und initialisiert sie.  */
  396. {
  397.   struct function_info *new;
  398.   new=mymalloc(sizeof(*new));
  399.   new->first_ic=new->last_ic=0;
  400.   new->vars=0;
  401.   new->inline_asm=0;
  402.   new->translation_unit=0;
  403.   new->used=new->modified=new->calls=0;
  404.   return new;
  405. }
  406. void free_fi(struct function_info *p)
  407. /*  Gibt ein function_info mit Inhalt frei.                     */
  408. {
  409.   if(p->first_ic) free_IC(p->first_ic);
  410.   if(p->vars) free_var(p->vars);
  411.   free(p->calls);
  412.   free(p->used);
  413.   free(p->modified);
  414.   free(p->inline_asm);
  415.   free(p);
  416. }
  417.  
  418.  
  419.